/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data;

import authentication.EncryptionType;
import connection.Account;
import connection.IReceiver;
import connection.SMTPAccount;
import data.contact.ContactFolder;
import data.email.AccountType;
import data.email.EmailFolder;
import data.email.EmailMessage;
import java.io.File;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.IIOException;
import org.apache.commons.lang3.StringUtils;
import xml.AccountFileHandler;

/**
 * Třída zapouzdřující přijímací a odesílací e-mailový účet do jednoho. Jde o
 * odpojenou třídu, které může pracovat i online.
 *
 * @author Arcanis
 */
public class Data extends Observable implements Observer {

    private Set<EmailFolder> folders = new LinkedHashSet<>();
    private AccountData senderAccountData = new AccountData();
    private AccountData receiverAccountData = new AccountData();
    private ContactFolder contacts = new ContactFolder("Kontakty");

    public Data() {
//        contacts.addContact(new Contact(new EmailAddress("arcanis@gmail.com")));
//        contacts.addContact(new Contact(new EmailAddress("arcanis1@gmail.com")));
//        contacts.addContact(new Contact(new EmailAddress("arcanis2@gmail.com")));
//        contacts.addContact(new Contact(new EmailAddress("arcanis3@gmail.com")));
        senderAccountData.setType(AccountType.POP3);
        senderAccountData.setType(AccountType.SMTP);
    }

    public synchronized void setFolders(List<EmailFolder> folder) {
        folders.clear();
        for (EmailFolder f : folder) {
            folders.add(f);
        }
        setChanged();
        notifyObservers();
    }

    public void loadAccount() {
//        AccountData ad = new AccountData();
//        ad.setEncryption(EncryptionType.SSL);
//        ad.setLogin("pokusny.moro@seznam.cz");
//        ad.setPass("pokuspokus");
//        ad.setServer("imap.seznam.cz");
////        ad.setLogin("pokusny2.moro@gmail.com");
////        ad.setPass("pokuspokus");
////        ad.setServer("imap.gmail.com");
//        ad.setType(AccountType.IMAP);        

        LoadMailsWorker w = new LoadMailsWorker(folders, receiverAccountData, this);
        w.execute();

    }

    public void init() throws Exception {
        loadContacts(new File("contacts.dat"));
        loadAccountData(new File("pokus.xml"));
        senderAccountData.addObserver(this);
        receiverAccountData.addObserver(this);
        contacts.addObserver(this);
        setChanged();
    }

    public void sendEmail(EmailMessage msg) throws Exception {
//         AccountData data = new AccountData();
//        data.setEncryption(EncryptionType.none);
//        data.setLogin("pokusny.moro@seznam.cz"); // @TODO replace
//        data.setPass("pokuspokus"); // @TODO replace
//        data.setServer("smtp.seznam.cz");
//        data.setType(AccountType.SMTP);
        SMTPAccount acc = new SMTPAccount(senderAccountData);
        acc.sendEmail(msg);
    }

    public ContactFolder getContacts() {
        return contacts;
    }

    public String[] getFolderNames() {
        Set<String> temp = new LinkedHashSet<>(this.folders.size());
        for (EmailFolder folder : folders) {
            temp.add(folder.getName());
        }
        return temp.toArray(new String[0]);
    }

    public synchronized boolean addFolder(String name) {
        if (getFolder(name) == null) {
            boolean stat = folders.add(new EmailFolder(name));
            setChanged();
            return stat;
        }
        return false;
    }

    public synchronized boolean removeFolder(String name) {
        EmailFolder folder = getFolder(name);
        if (folder != null) {
            boolean stat = folders.remove(folder);
            setChanged();
            return stat;
        }
        return false;
    }

    public EmailFolder getFolder(String name) {
        for (EmailFolder folder : folders) {
            if (StringUtils.equals(folder.getName(), name)) {
                return folder;
            }
        }
        return null;
    }

    public AccountData getSenderAccountData() {
        return senderAccountData;
    }

    public void setSenderAccountData(AccountData accountData) {
        this.senderAccountData = accountData;
    }

    public AccountData getReceiverAccountData() {
        return receiverAccountData;
    }

    public void setReceiverAccountData(AccountData accountData) {
        this.receiverAccountData = accountData;
    }

    /**
     * Loads the sender and receiver data.
     *
     * @param file
     * @throws IIOException
     */
    public void loadAccountData(File file) throws IIOException, Exception {
        //@TODO account???
        AccountFileHandler handler = new AccountFileHandler(file);
        handler.LoadData("arcaniscz@gmail.com");
        this.receiverAccountData = handler.GetReceiverData();
        this.senderAccountData = handler.GetSenderData();

        if (receiverAccountData == null || senderAccountData == null) {
            receiverAccountData = null;
            senderAccountData = null;
            throw new Exception("Error while loading");
        }

        setChanged();
    }

    /**
     * Saves the sender and receiver data.
     *
     * @param file
     * @throws IIOException
     */
    public void saveAccountData(File file) throws IIOException, Exception {
        // @TODO account???              
        AccountFileHandler handler = new AccountFileHandler(file);
        handler.SaveData(receiverAccountData, senderAccountData, "arcaniscz@gmail.com");
    }

    public void loadContacts(File file) {
        this.contacts.load(file);
        setChanged();
        notifyObservers();
    }

    public void saveContacts(File file) {
        this.contacts.save(file);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof AccountData) {
            try {
                this.saveAccountData(new File("pokus.xml"));
            } catch (IIOException ex) {
                Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (o instanceof ContactFolder) {
            System.out.println("Ukladam!");
            saveContacts(new File("contacts.dat"));
        }
    }
}
